#include "logical.h"
#include <QSound>

Logical::Logical()
{

}

//建图
void Logical:: buildMap(int gemnums){

    vector<int> mm(8);
    int gStoneNumber;
    //随机生成宝石
    srand((int)time(0));
    for(int i=0;i<8;i++){
        for(int j=0;j<8;j++){
            gStoneNumber=rand()%gemnums+1;//生成1-gemspecies的随机数
//            mm.push_back(gStoneNumber);
            gemstNcord[i][j]=gStoneNumber;
        }
//        gemstNcord.push_back(mm);
//        mm.clear();
    }
    while(checkMap()){
        //判断横向是否有相邻的三个宝石相同
        for(int j=0;j<8;j++){
            //i<6 最后查的是567位置上的
            for(int i=0;i<6;i++){
                if(gemstNcord[j][i]==gemstNcord[j][i+1]&&gemstNcord[j][i+1]==gemstNcord[j][i+2]){
                    //随机生成宝石，并判断是否相等，若中间宝石与两边依旧相等则继续随机生成
                    while(gemstNcord[j][i]==gemstNcord[j][i+1]){

                        gemstNcord[j][i+1]=rand()%8+1;
                    }
                }
            }
        }
        //判断纵向是否有相邻的三个宝石相同
        for(int j=0;j<8;j++){
            for(int i=0;i<6;i++){
                if(gemstNcord[i][j]==gemstNcord[i+1][j]&&gemstNcord[i+1][j]==gemstNcord[i+2][j]){
                     //随机生成宝石，并判断是否相等，若中间宝石与两边依旧相等则继续随机生成
                    while(gemstNcord[i][j]==gemstNcord[i+1][j]){
                        gemstNcord[i+1][j]=rand()%8+1;
                    }
                }
            }
        }
    }

    for(int n=0;n<8;n++){
        QString temp="";
        for(int m =0;m<8;m++){
            temp+=QString::number(gemstNcord[n][m]);
        }
        qDebug()<<temp;
    }
}

//检查是否有三连，若有，返回true
bool Logical::checkMap(){
    //判断横向是否有相邻的三个宝石相同
    for(int j=0;j<8;j++){
        for(int i=0;i<6;i++){
           //用于检查宝石是否相同 检查第j行第i,i+1,i+2位置上的相连三个宝石是否相等
            if(gemstNcord[j][i]==gemstNcord[j][i+1]&&gemstNcord[j][i+1]==gemstNcord[j][i+2]){
                return true;
            }
        }
    }

    //判断纵向是否有相邻的三个宝石相同
    for(int j=0;j<8;j++){
        for(int i=0;i<6;i++){
            if(gemstNcord[i][j]==gemstNcord[i+1][j]&&gemstNcord[i+1][j]==gemstNcord[i+2][j]){
                return true;
            }
        }
    }
    return false;
}


bool Logical::eliminate(){
    int current = 0;//当前宝石颜色
    int fzMap[8][8];
    memcpy(fzMap, gemstNcord, sizeof(gemstNcord));
    bool ischange=false;
    for(int j=0;j<8;j++){

        //i<6 最后查的是567位置上的
        for(int i=0;i<6;i++){
            if(gemstNcord[j][i]==gemstNcord[j][i+1]&&gemstNcord[j][i+1]==gemstNcord[j][i+2]){
                //随机生成宝石，并判断是否相等，若中间宝石与两边依旧相等则继续随机生成
                fzMap[j][i]=0;
                fzMap[j][i+1]=0;
                fzMap[j][i+2]=0;
                ischange=true;
                /*五***********连*/
            }
        }
    }

    //判断纵向是否有相邻的三个宝石相同
    for(int j=0;j<8;j++){
        for(int i=0;i<6;i++){
            if(gemstNcord[i][j]==gemstNcord[i+1][j]&&gemstNcord[i+1][j]==gemstNcord[i+2][j]){
                 //随机生成宝石，并判断是否相等，若中间宝石与两边依旧相等则继续随机生成
                fzMap[i][j]=0;
                fzMap[i+1][j]=0;
                fzMap[i+2][j]=0;
                ischange=true;
                /*五**********连*/
            }
        }
    }
    memcpy(gemstNcord, fzMap, sizeof(fzMap));
    return ischange;
}

bool Logical::swap(int a, int b, int m, int n){
    /*游戏暂停时应该停止判断*/
    //判断是否同行
        if(a==m){
            //判断是否相邻
            if(((b-n)==1)||((b-n)==-1)){
                int mid= gemstNcord[a][b];
                 gemstNcord[a][b]= gemstNcord[m][n];
                 gemstNcord[m][n]=mid;
                if(checkMap()){
                    return true;
                }else{
                    mid= gemstNcord[a][b];
                    gemstNcord[a][b]= gemstNcord[m][n];
                    gemstNcord[m][n]=mid;
                    return false;
                }
            }else{
                return false;
            }
        }else{
            if(b==n){//同列？
                if(((a-m)==1)or((a-m)==-1)){//相邻？
                    int mid= gemstNcord[a][b];
                    gemstNcord[a][b]=gemstNcord[m][n];
                    gemstNcord[m][n]=mid;
                    if(checkMap()){
                        return true;
                    }else{
                        mid=gemstNcord[a][b];
                        gemstNcord[a][b]=gemstNcord[m][n];
                        gemstNcord[m][n]=mid;
                        return false;
                    }
                    return true;
                }else{
                    return false;
                }
            }else{
                return false;
            }
        }
}

bool Logical::down(){
    srand(GetTickCount());
    int isChanged = false;
    for(int i = 0; i < 8; i++)
    {
        for(int j = 7; j >= 0; j--)
        {
            //从下往上判断依次判断第8行第一个，第七行第一个，第六行第一个...然后第一行第一个，第八行第二个....
            if(gemstNcord[j][i] == 0)
            {
            //如果第j行第i个为空，则将其上方的点依次下移
                for(int k = j; k > 0; k--)
                {
                    gemstNcord[k][i] =gemstNcord[k - 1][i];
                }
                gemstNcord[0][i] = rand()%8 + 1;
                isChanged = true;
                break;
            }
        }
    }
    return isChanged;
}


//提示
int Logical::hint(){
    int meiyong=0;
    int map[8][8];
    int i,j;
    int mid;//交换过渡
    int tap = 0;//判断找到没有
    int canExc = 0;
    //把地图拷贝
    for(i = 0; i < 8; i++){
            for(j = 0; j < 8; j++){
                map[i][j]=gemstNcord[i][j];
            }
        }

    for(i = 0; i < 7; i++){
        for(j = 0; j < 8; j++){
            mid = map[i][j];
            map[i][j] = map[i+1][j];//对每一个的行交换进行判断
            map[i+1][j] = mid;

            int a,b;
            for(b = i; b <= i+1; b++){
                canExc = 0;
                for(a = 0; a < 6; a++){
                    if(map[b][a]==map[b][a+1]&&map[b][a+1]==map[b][a+2]){
                        canExc = 1;
                        //能消除就跳出循环

                        break;
                    }else{
                        canExc = 0;
                    }
                 }
                if(canExc==1){
                    break;
                }
             }
             //如果同行没有可以消的，判断列
             if(canExc == 0){
                a = j;
                for(b = 0; b < 6; b++){
                    if(map[b][a]==map[b+1][a]&&map[b+1][a]==map[b+2][a]){
                        canExc = 1;

                        break;
                     }else{
                        canExc = 0;
                     }
                 }

              }
              if(canExc == 1){
                 //如果可以交换，返回可交换的坐标
                 //返回列交换
                 swaPoint[0][0] = i;
                 swaPoint[0][1] = j;
                 swaPoint[1][0] = i+1;
                 swaPoint[1][1] = j;
                 tap = 1;//能交换tap为1

                 return canExc;
               }else{
                  //列不能交换坐标恢复
                  mid = map[i][j];
                  map[i][j] = map[i+1][j];
                  map[i+1][j] = mid;
                  tap = 0;
               }

        }

    }

//如果hang交换失败，在lie交换上判断

        for(i = 0; i < 8; i++){
            for(j = 0; j < 7; j++){
                mid = map[i][j];
                map[i][j] = map[i][j+1];
                map[i][j+1] = mid;

                int a,b;
                for(b = i; b <= i+1; b++){
                    canExc = 0;
                    for(a = 0; a < 6; a++){
                        if(map[a][b]==map[a+1][b]&&map[a+1][b]==map[a+2][b]){
                            canExc = 1;

                            break;
                         }else{
                            canExc = 0;
                         }
                     }
                    if (canExc==1)
                        break;
                 }
                 if(canExc == 0){
                     a = i;
                     for(b = 0; b < 6; b++){
                         if(map[a][b]==map[a][b+1]&&map[a][b+1]==map[a][b+2]){
                             canExc = 1;
                             break;
                          }else{
                             canExc = 0;
                          }
                     }
                     if (canExc==1)
                         break;
                  }
                  if(canExc == 1){
                      swaPoint[0][0] = i;
                      swaPoint[0][1] = j;
                      swaPoint[1][0] = i;
                      swaPoint[1][1] = j+1;
                      tap = 1;

                      return canExc;

                   }else{
                      mid = map[i][j];
                      map[i][j] = map[i][j+1];
                      map[i][j+1] = mid;
                       tap = 0;
                   }
            }
        }

//这不能再出错了吧！
    return canExc;
}

